package com.huaxin.feignclient;

import feign.Logger;
import feign.Request;
import feign.Retryer;
import feign.codec.ErrorDecoder;
import org.springframework.context.annotation.Bean;

/**
 * OpenFeign 全局配置（无 @Configuration 注解，避免被自动扫描）
 * 由具体模块通过 @EnableFeignClients 导入
 */
public class FeignConfiguration {

    /**
     * 日志级别
     */
    @Bean
    public Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL; // 可改为 BASIC / HEADERS / NONE
    }

    /**
     * 自定义请求配置（连接/读取超时、重试）
     */
    @Bean
    public Request.Options options() {
        return new Request.Options(
                5000,           // 连接超时：5秒
                10000,          // 读取超时：10秒
                true            // 是否使用缓存策略
        );
    }

    /**
     * 自定义重试机制
     */
    @Bean
    public Retryer retryer() {
        return new Retryer.Default(
                1000,   // 初始重试间隔 1s
                3000,   // 最大间隔 3s
                3       // 最多重试 3 次（共尝试 4 次）
        );
    }

    /**
     * 统一错误解码器
     */
    @Bean
    public ErrorDecoder errorDecoder() {
        return (methodKey, response) -> {
            // 可根据 response.status() 记录日志或抛出自定义异常
            return switch (response.status()) {
                case 404 -> new ResourceNotFoundException("资源未找到: " + methodKey);
                case 500 -> new RemoteServiceException("远程服务内部错误");
                case 503 -> new ServiceUnavailableException("服务暂时不可用");
                default -> new FeignException("Feign调用失败: " + response.status());
            };
        };
    }

    /**
     * 可选：添加统一请求拦截器（如：传递 Token、TraceID）
     */
    @Bean
    public feign.RequestInterceptor requestInterceptor() {
        return requestTemplate -> {
            // 示例：传递 JWT Token（从 SecurityContext 获取）
            // String token = SecurityContextHolder.getContext().getAuthentication().getCredentials().toString();
            // requestTemplate.header("Authorization", "Bearer " + token);

            // 示例：传递链路追踪ID
            requestTemplate.header("X-Trace-ID", java.util.UUID.randomUUID().toString());
        };
    }
}